


// ele    运动的元素
// params  传入一个对象 (包含运动的属性及其终点值)
// type    运动的方式  (slow  normal  fast)
// callback  接收一个函数,每次运动完毕之后执行

// 问题: 计时器的编号时全局变量  每次调用animate -> 先清除上一个,在启动下一个  -> 始终只有一个(下面的跑 上面的就停下来了)
function animate(ele, params, type = "normal", callback) {
    // debugger;
    // callback 形参 -> 接收实际参数(本次有点特殊 -> 接收的是一个函数) 

    // 记录单属性运动的 cur end speed
    // var cur = ele.offsetLeft;  // 1. 记录小球的起始位置(left)  2. 每次运动后小球的位置
    // var cur = parseFloat(getStyle(ele, cssKey));  // 1. 记录小球的起始位置(left)  2. 每次运动后小球的位置
    // end = parseFloat(end); //去单位 ("1000px" => 1000)
    // var speed = 0;

    var cur = {};   // {left:当前值,top:当前值}
    var end = {};   // {left:终点,top:终点}  单位处理
    var speed = {}  // {left:速度,top:速度}  记录速度

    for (var cssKey in params) {  // csskey => 运动的css属性
        cur[cssKey] = parseFloat(getStyle(ele, cssKey));
        end[cssKey] = parseFloat(params[cssKey]);
        speed[cssKey] = 0;
    }
    // console.log("起始位置", cur);
    // console.log("终点", end);
    // console.log("速度", speed);

    // ele => 运动的元素(元素节点 -> 对象)  -> 元素节点的内置属性(className,id) 和 对象自定义属性
    // var data = {};
    // data.a = 1;
    // data.b = 2;

    // 将计时器的编号 作为元素的属性 存储到元素上(每个运动的元素都有一个timer属性 => 计时器的编号)
    // ele.timer = 1;

    clearInterval(ele.timer);
    ele.timer = setInterval(function () {

        // 多属性同时运动
        var isFinished = true;  // 假设都到达终点

        // {left:"1000px",top:500}
        for (var cssKey in params) {  // csskey => 运动的css属性  "left"  "top"

            if (type == "normal") {
                // 匀速运动
                if (end[cssKey] > cur[cssKey]) {
                    speed[cssKey] = 20
                } else if (end[cssKey] < cur[cssKey]) {
                    speed[cssKey] = -20;
                } else {
                    speed[cssKey] = 0;
                }

            } else if (type == "fast") {
                // 加速运动
                if (end[cssKey] > cur[cssKey]) {  // 正向运动(0-1000   => speed正值)  
                    speed[cssKey] += 2;
                } else if (end[cssKey] < cur[cssKey]) { // 反向运动(1000 - 0   => speed负值) 
                    speed[cssKey] -= 2;
                } else {
                    speed[cssKey] = 0;
                }

            } else if (type == "slow") {
                // 缓冲运动
                // (终点值 - 当前位置)  => 剩余的距离
                // 剩余的距离 / 缓冲因子(n) => (每次剩余的n分之1)

                // 缓冲因子 => 一般在8-12之间

                if (end[cssKey] > cur[cssKey]) {
                    speed[cssKey] = (end[cssKey] - cur[cssKey]) / 10;  // speed >0 =>  可能会出现 0.00001
                    speed[cssKey] = Math.ceil(speed[cssKey]);  //  如果速度小于1  取  1
                } else if (end[cssKey] < cur[cssKey]) {
                    speed[cssKey] = (end[cssKey] - cur[cssKey]) / 10;  // speed < 0 =>  可能会出现-0.00001
                    speed[cssKey] = Math.floor(speed[cssKey]);  //  如果速度大于-1  取  -1
                } else {
                    speed[cssKey] = 0;
                }

            }

            // console.log(speed);
            cur[cssKey] += speed[cssKey];  // 每次运动后小球的位置
            ele.style[cssKey] = cur[cssKey] + "px";

            if (Math.abs(cur[cssKey] - end[cssKey]) <= Math.abs(speed[cssKey])) {  // 到达终点后停下
                ele.style[cssKey] = end[cssKey] + "px";  // 直接到达终点
                delete params[cssKey];   //如果当前属性到达终点 => 移出该属性 (不会再遍历该属性)
                // clearInterval(timer);   // 有一个到达终点就停下  
            } else {  // 有一个没到达终点   => 推翻假设
                isFinished = false;
            }


        }
        // console.log(isFinished);
        if (isFinished) {   ///全都到达终点(本次运动结束)=> 清除计时器
            clearInterval(ele.timer);
            if (callback && typeof callback == "function") {  //如果callback有值 且 是函数
                callback(); //执行该函数  -> 每次运动结束之后执行函数
            }
        }

    }, 10);
}

/* 获取非行内样式 */
function getStyle(ele, cssKey) {
    if (window.getComputedStyle) {
        return window.getComputedStyle(ele)[cssKey];
    } else {
        return ele.currentStyle[cssKey];
    }
}

